home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-05-14 | 50.5 KB | 1,976 lines |
- Newsgroups: comp.sources.misc
- From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
- Subject: v06i107: glib part 6 of 15
- Reply-To: lee@uhccux.uhcc.Hawaii.Edu (Greg Lee )
-
- Posting-number: Volume 6, Issue 107
- Submitted-by: lee@uhccux.uhcc.Hawaii.Edu (Greg Lee )
- Archive-name: glib/part06
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 6 (of 15)."
- # Contents: PORTING k1multi.mnu pc-ints.asm pc-mach.c
- # Wrapped by lee@uhccux on Sun May 7 00:40:13 1989
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'PORTING' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'PORTING'\"
- else
- echo shar: Extracting \"'PORTING'\" \(12157 characters\)
- sed "s/^X//" >'PORTING' <<'END_OF_FILE'
- X$Id: PORTING,v 1.6 89/05/06 17:13:07 lee Exp $
- X[Lee:]
- X
- XThe C source code for the various synth modules is generated by
- Xa program 'menutoc'. Although C source for 'menutoc' is included,
- Xrevising the program would require flex, the freely distributed "fast
- Xlex" to compile. But if you happen not to have flex, lex will serve --
- Xsee the note in the Makefile and notes at the beginning of file
- Xmakemenu.l.
- X
- X ---------------------------------
- X[Kesti:]
- X
- XIn order to adapt it to the D-10's rather large data set, I have used glib's
- Xability to service multiple synths to instead service sub-sections of a single
- XD-10. These subsections are:
- X
- X Performance mode patches
- X Multi-timbral mode timbres
- X
- X Tone waveform generators
- X Tone time variant filters
- X Tone time variant amplifiers
- X
- X Rhythm setup
- X Rhythm patterns
- X Rhythm track
- X
- XBecause the memory requirement of a single program to service this much data
- Xis large enough to be cumbersome, I have broken the subsections into three
- Xseparate programs. These are d10patch, d10tone, and d10drum.
- X
- XThe tone services also require a separate program because, unlike all other
- Xservices, they must operate on a single common data set. This required
- Xchanges to the data memory allocation and other functions in glib.c. When
- Xcompiling d10tone, be sure to #define SINGLEDATA in glib.c to enable these
- Xchanges.
- X
- XI believe that I have maintained glib's ability to be compiled for Un*x
- X(using SysV curses), DOS, and the Atari ST. The sources supplied have
- Xbeen succesfully compiled and run on an AT&T 3b1, running v3.51 software;
- Xand an AT&T 6300 (with a V30 in the cpu socket), running AT&T's version of
- XDOS v3.20. Borland Turbo C v1.0 was used to produce the executables and the
- Xmachine was fitted with a CMS-401 interface.
- X
- XThe Makefile provided was used on the 3b1, and produces a single executable
- Xnamed glib that combines all services, but does not tie the tone data
- Xtogether as discussed above. This is presumably no problem, as the Un*x
- Xversion is intended to be for demo purposes. If your Un*x machine has a
- Xmidi interface, I'd like hear from you!
- X
- XThe Turbo C project files (*.prj) are used by the integrated environment to
- Xproduce glib.exe, d10patch.exe, d10tone.exe, and d10drum.exe. Be sure to
- Xuse the large memory model. It is not recommended that glib.exe be used, as
- Xit requires almost all the available memory of a 640K machine, and again,
- Xwould not tie the tone data together (SINGLEDATA should not be #defined
- Xwhen compiling for glib.exe.).
- X
- X[Lee:]
- X
- XI did not include the .prj files mentioned above. So many files
- Xalready! But below are the contents of those files. The file machdep.c
- Xis a copy of pc-mach.c (and pc-mach.h should be copied to machdep.h);
- Xthe d10*.c files except d10ton.c) must be constructed from the
- Xcorresponding d10*.mnu files by the menutoc program; and the files
- Xlistdrum.c, listpat.c, and listton.c are the same as file list.c, but
- Xwith '#defines' removed for the unused modules. That is to say, for the
- XD10 '#defines', keep only
- X #define D10urp
- X #define D10rsu
- X #define D10tra
- Xfor listdrum.c, keep only
- X #define D10pat
- X #define D10tim
- Xfor listpat.c, and keep only
- X #define D10wfg
- X #define D10tvf
- X #define D10tva
- Xfor listton.c.
- X::::::::::::::
- Xcontents of file d10drum.prj
- X::::::::::::::
- Xd10urp.c
- Xd10rsu.c
- Xd10tra.c
- Xglib.c
- Xlistdrum.c
- Xvis.c
- Xmachdep.c
- X::::::::::::::
- Xcontents of file d10patch.prj
- X::::::::::::::
- Xd10pat.c
- Xd10tim.c
- Xglib.c
- Xlistpat.c
- Xvis.c
- Xmachdep.c
- X::::::::::::::
- Xcontents of file d10tone.prj
- X::::::::::::::
- Xd10ton.c
- Xd10wfg.c
- Xd10tvf.c
- Xd10tva.c
- Xglib.c
- Xlisttone.c
- Xvis.c
- Xmachdep.c
- X::::::::::::::
- Xcontents of file glib.prj
- X::::::::::::::
- Xd10pat.c
- Xd10tim.c
- Xd10wfg.c
- Xd10ton.c
- Xd10tvf.c
- Xd10tva.c
- Xd10urp.c
- Xd10rsu.c
- Xd10tra.c
- Xglib.c
- Xlist.c
- Xvis.c
- Xmachdep.c
- X----------------------
- X
- X
- X[Thompson:]
- X
- XCompiling
- X---------
- Xmachdep.c and machdep.h are machine-dependent parts. The *-mach.h and
- X*-mach.c files are the versions of these files for different machines,
- Xe.g. unix-mach.[ch] is for UNIX, st-mach.[ch] is for the Atari ST.
- XCopy the proper files to machdep.c and machdep.h before compiling
- Xfor a particular machine. For example, on UNIX, do the following:
- X
- X cp unix-mach.c machdep.c
- X cp unix-mach.h machdep.h
- X make glib
- X
- XThe contents of list.c control which synths are supported; modify
- Xthe defines at the beginning of that file appropriately. When
- Xcompiling, you need to include glib.c and the appropriate synth
- Xfiles (e.g. if you define DW8000 in list.c, then you need to compile
- Xwith dw8000.c). A single version of glib can support as many synths
- Xas you want, although some compilers may have size limitations or
- Xoverlay schemes that get in the way.
- X
- X
- XHacking glib - Internals
- X------------------------
- XThe program is written so that support for a new synth can be added by
- Xadding an entry to the array in list.c, describing the various attributes
- Xof the synthesizer and the C functions to be called to control it. And, of
- Xcourse, you have to write those C functions. Adding a new synth, for a
- Xreasonable C programmer, might be described as mostly straightforward but
- Xtedious. People other than the original author HAVE done it, with no help.
- XGlib allows you to re-use the front-end interface of the librarian and
- Xeditor, but it does not relieve you of having to write C code which
- Xinteracts with the synth (which, depending on the synth, can of course be
- Xeasy or maddening) and with the raw data formats. Naturally, using one of
- Xthe existing synth files as an example of how to do things is the best way
- Xto start on a new one.
- X
- XThe 'E' array in list.c has the following structure:
- X
- Xstruct editinfo {
- X char *ed_name; /* Synth name */
- X struct paraminfo *ed_params; /* list of parameters */
- X struct labelinfo *ed_labels; /* screen labels in edit mode */
- X int ed_nvoices; /* number of voices */
- X int ed_vsize; /* size of each voice data, in bytes */
- X int ed_nsize; /* name size */
- X int ed_dataid; /* data ID */
- X int (*ed_din)(); /* copy voice data into paraminfo array */
- X int (*ed_dout)(); /* copy voice data out of paraminfo array */
- X int (*ed_sedit)(); /* send 1 voice to synth edit buffer */
- X int (*ed_sone)(); /* send 1 voice to a synth (permanent) patch*/
- X int (*ed_sbulk)(); /* send bulk voice data */
- X int (*ed_gbulk)(); /* get bulk voice data */
- X char *(*ed_nof)(); /* get name of a voice out of data */
- X int (*ed_snof)(); /* set name of a voice in data */
- X char *(*ed_numof)(); /* convert voice number to on-screen text */
- X int (*ed_cvtnum)(); /* convert visable voice number to std. format */
- X};
- X
- XIn glib, there are several relatively independent representations of the
- Xsynth voice data. First, there is the data that is stored in the
- Xlibrary and synth banks (ie. the data used and manipulated via the
- Xlibrarian screen). This is the format of the data that is written to
- Xand read from files (a single byte, given as 'ed_dataid' above, is added
- Xto the beginning of the file, to identify it). The size of a single
- Xvoice in this data is 'ed_vsize'. The number of voices in a bank is
- X'ed_nvoices', so the amount of space taken up by a library bank is
- Xed_vsize * ed_nvoices.
- X
- XWhen a voice is edited, the voice data is copied into the parameter
- Xarray (see below), in p_val. The 'ed_din' function is called to do this.
- XAfter a voice is edited, 'ed_dout' takes the updated parameter values
- Xand puts them back into the original data format. Note that this means
- Xthat the bytes in the 'raw' voice data and the values in the parameter
- Xarray (ie. the values manipulated by the editor) need not be the same.
- XThere are utility functions 'getval' and 'setval' which should be used
- Xfor getting and setting the values in the parameter array. See dx100.c
- Xfor usage.
- X
- XThe ed_sedit, ed_sone, ed_sbulk, and ed_gbulk functions are called to
- Xsend voices to and get voices from the synthesizer. Only one of ed_sone
- Xand ed_sbulk need be defined, although ed_sone should be preferred.
- X(I had trouble getting the DX100 to accept a single permanent voice
- Xchange, so it always does a bulk voice transfer.) The data passed to
- Xthese functions is in the library bank format. The ed_gbulk function is
- Xoptional, so that write-only MIDI devices (like the DEP-5) are allowed.
- X
- XThe ed_nof function is called to pull the voice name out of the raw
- Xvoice data (as stored in the library banks), and it should return a
- XC string containing the name. The ed_snof function is called to
- Xstick a voice name into the raw voice data. Note that the 'raw'
- Xlibrary bank voice data does NOT have to match the data that is
- Xreally sent to the synthesizer (by the ed_sedit and ed_sone functions).
- XFor example, the DEP-5 does not have names as part of the voice data,
- Xbut that does not prevent glib from maintaining and storing (in the files)
- Xvoice names. This holds for the DW-8000 as well.
- X
- XThe ed_numof function is called to convert the voice number to the
- Xtext that is displayed on the librarian screen. This can handle
- Xthe odd numbering convention of the DW-8000. If ed_numof==NULL, the
- Xnumber is used as-is. Otherwise, ed_numof is called with the voice
- Xnumber MINUS 1 (i.e. 0-based); ed_numof should return a string
- Xcontaining the desired display. Likewise, the ed_cvtnum function is
- Xused to convert user input from an odd numbering system to the standard
- Xsequential internal representation (0 to whatever).
- X
- XThe editor screen is controlled by two arrays, ed_labels and ed_params.
- Xed_labels contains arbitrary screen labels, in the following structure:
- X
- Xstruct labelinfo {
- X int l_row; /* 0-based */
- X int l_col; /* 0-based */
- X char *l_text;
- X};
- X
- XThe ed_params array is used to specify the parameters that the user can peruse
- Xand change in the edit screen, and looks like this (one for each parameter):
- X
- Xstruct paraminfo {
- X char *p_name; /* the parameter name */
- X char *p_label; /* on-screen label (possibly NULL) */
- X int p_lrow; /* position for printing label */
- X int p_lcol;
- X int p_vrow; /* position for printing value */
- X int p_vcol;
- X char *((*p_tovis)()); /* function converts value to on-screen text*/
- X int p_min; /* minimum parameter value */
- X int p_max; /* maximum parameter value */
- X int p_val; /* parameter value */
- X int p_flags; /* flag to enable/disable parameter */
- X};
- X
- XThe editor calls p_tovis with a parameter value, and expects that function
- Xto pass back a string which contains what should be displayed on the
- Xscreen for that value. Often, this is just an 'sprintf' of the value,
- Xor perhaps the value offset by something. Or, it could be some text
- Xthat represents the value (e.g. "on" for 1 and "off" for 0). Or, it could
- Xbe something more interesting, e.g. a picture of the voice algorithm.
- XThe parameter value strings can make use of cursor motion, by including the
- Xsequences ~d,~u,~l,~r to go down,up,left,right. The dx100 and dep5 editors
- Xuse this to handle the display of the algorithm drawings.
- X
- XA parameter can be 'disabled' by setting p_flags to non-zero. The p_tovis
- Xfunction can set the external variable 'Redraw' to 1 if it wants to force
- Xthe entire editor screen to be redrawn (e.g. after a parameter has been
- Xdisabled).
- X
- XSupport for a mouse has been added, although it is currently disabled
- Xfor the Atari, since I was having various hassles getting it under control.
- XIt did work, but had various quirks.
- X
- XMouse support for the Amiga was added, and appears to work after fixing
- Xa few problems in glib.c, so it may be possible to enable the Atari mouse
- Xsupport now.
- X
- X ...Tim Thompson...twitch!glimmer!tjt...
- X
- X[notes from Ed Wilts, ewilts%Janus.MtRoyal.AB.CA@Ucnet.UCalgary.CA,
- X on the Amiga version for the D-10]
- X
- X... The problem I had in getting it
- Xgoing was more in the execution than the compilation. Without a sufficiently
- Xlarge stack, you will get highly intermittent results, and depending on the
- Xstate of the moon and the time of day, gurus. I was getting frequent timeouts
- Xreading from the D-10 and sometimes the data would be all read but not in the
- Xproper order. I was getting quite frustrated for a while...
- X
- XMy stack was originally 4000 - the default. I boosted it to 8192 with no
- Xgreater results, and finally went to 32768 and now it seems to work. At least
- XI can read from the D-10 consistently. ...
- END_OF_FILE
- if test 12157 -ne `wc -c <'PORTING'`; then
- echo shar: \"'PORTING'\" unpacked with wrong size!
- fi
- # end of 'PORTING'
- fi
- if test -f 'k1multi.mnu' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'k1multi.mnu'\"
- else
- echo shar: Extracting \"'k1multi.mnu'\" \(10993 characters\)
- sed "s/^X//" >'k1multi.mnu' <<'END_OF_FILE'
- X/* $Id: k1multi.mnu,v 1.6 89/05/06 17:13:27 lee Exp $
- X * GLIB - a Generic LIBrarian and editor for synths
- X *
- X * K1 Patch Librarian
- X *
- X * Adapted for K1 from Kesti's D10 version by Greg Lee
- X * $Log: k1multi.mnu,v $
- X * Revision 1.6 89/05/06 17:13:27 lee
- X * rel. to comp.sources.misc
- X *
- X */
- X
- X#include "glib.h"
- X#include "k1vis.h"
- X
- X#define K1MULTISIZE 75
- X#define K1SINGLESIZE 87
- X#define RESERVESIZE 0
- X
- Xextern char sngnames[64][11];
- X
- X/* This array contains arbitrary screen labels */
- Xstruct labelinfo Lk1m[] = {
- X
- X#MENU for multi
- X volume %
- X
- X
- X
- X
- X A......... B................ C............. D.....................
- X single zn lo zn hi vel sw poly mode rcvch trnsps tune level output
- X |-------------|-----|-----|------|----|----|-----|------|----|-----|------|
- X
- X1 % % % % % % % % % % %
- X2 % % % % % % % % % % %
- X3 % % % % % % % % % % %
- X4 % % % % % % % % % % %
- X5 % % % % % % % % % % %
- X6 % % % % % % % % % % %
- X7 % % % % % % % % % % %
- X8 % % % % % % % % % % %
- X
- X
- X
- X
- X
- X Press SPACE BAR to sound note % at volume % for duration % on channel % .
- X#END
- X
- X-1,-1,NULL
- X};
- X
- Xchar *vismltnum();
- X
- Xstruct paraminfo Pk1m[] = {
- X
- X/*NAME TYPE POS MAX OFFSET MASK SHIFT ADHOC*/
- X
- X#O volume pnum %% 99 10
- X
- X#O single1 mltnum %% 63 11
- X#O zonelo1 cpitch %% 127 19
- X#O zonehi1 cpitch %% 127 27
- X#O velosw1 velosw %% 2 43 0x30 4
- X#O poly1 poly %% 9 35 0x0F
- X#O modem1 mode %% 2 35 0x40 6 *1
- X/* 2nd bit below goes above */
- X#O moden1 num -- 1 43 0x40 6 *2
- X#O rcvch1 pnum %% 15 43 0x0F
- X#O trnsps1 keyshift %% 48 51
- X#O tune1 finetune %% 100 59
- X#O level1 num %% 100 67
- X#O output1 pan %% 2 35 0x30 4
- X
- X#O single2 mltnum %% 63 12
- X#O zonelo2 cpitch %% 127 20
- X#O zonehi2 cpitch %% 127 28
- X#O velosw2 velosw %% 2 44 0x30 4
- X#O poly2 poly %% 9 36 0x0F
- X#O modem2 mode %% 2 36 0x40 6 *1
- X#O moden2 num -- 1 44 0x40 6 *2
- X#O rcvch2 pnum %% 15 44 0x0F
- X#O trnsps2 keyshift %% 48 52
- X#O tune2 finetune %% 100 60
- X#O level2 num %% 100 68
- X#O output2 pan %% 2 36 0x30 4
- X
- X#O single3 mltnum %% 63 13
- X#O zonelo3 cpitch %% 127 21
- X#O zonehi3 cpitch %% 127 29
- X#O velosw3 velosw %% 2 45 0x30 4
- X#O poly3 poly %% 9 37 0x0F
- X#O modem3 mode %% 2 37 0x40 6 *1
- X#O moden3 num -- 1 45 0x40 6 *2
- X#O rcvch3 pnum %% 15 45 0x0F
- X#O trnsps3 keyshift %% 48 53
- X#O tune3 finetune %% 100 61
- X#O level3 num %% 100 69
- X#O output3 pan %% 2 37 0x30 4
- X
- X#O single4 mltnum %% 63 14
- X#O zonelo4 cpitch %% 127 22
- X#O zonehi4 cpitch %% 127 30
- X#O velosw4 velosw %% 2 46 0x30 4
- X#O poly4 poly %% 9 38 0x0F
- X#O modem4 mode %% 2 38 0x40 6 *1
- X#O moden4 num -- 1 46 0x40 6 *2
- X#O rcvch4 pnum %% 15 46 0x0F
- X#O trnsps4 keyshift %% 48 54
- X#O tune4 finetune %% 100 62
- X#O level4 num %% 100 70
- X#O output4 pan %% 2 38 0x30 4
- X
- X#O single5 mltnum %% 63 15
- X#O zonelo5 cpitch %% 127 23
- X#O zonehi5 cpitch %% 127 31
- X#O velosw5 velosw %% 2 47 0x30 4
- X#O poly5 poly %% 9 39 0x0F
- X#O modem5 mode %% 2 39 0x40 6 *1
- X#O moden5 num -- 1 47 0x40 6 *2
- X#O rcvch5 pnum %% 15 47 0x0F
- X#O trnsps5 keyshift %% 48 55
- X#O tune5 finetune %% 100 63
- X#O level5 num %% 100 71
- X#O output5 pan %% 2 39 0x30 4
- X
- X#O single6 mltnum %% 63 16
- X#O zonelo6 cpitch %% 127 24
- X#O zonehi6 cpitch %% 127 32
- X#O velosw6 velosw %% 2 48 0x30 4
- X#O poly6 poly %% 9 40 0x0F
- X#O modem6 mode %% 2 40 0x40 6 *1
- X#O moden6 num -- 1 48 0x40 6 *2
- X#O rcvch6 pnum %% 15 48 0x0F
- X#O trnsps6 keyshift %% 48 56
- X#O tune6 finetune %% 100 64
- X#O level6 num %% 100 72
- X#O output6 pan %% 2 40 0x30 4
- X
- X#O single7 mltnum %% 63 17
- X#O zonelo7 cpitch %% 127 25
- X#O zonehi7 cpitch %% 127 33
- X#O velosw7 velosw %% 2 49 0x30 4
- X#O poly7 poly %% 9 41 0x0F
- X#O modem7 mode %% 2 41 0x40 6 *1
- X#O moden7 num -- 1 49 0x40 6 *2
- X#O rcvch7 pnum %% 15 49 0x0F
- X#O trnsps7 keyshift %% 48 57
- X#O tune7 finetune %% 100 65
- X#O level7 num %% 100 73
- X#O output7 pan %% 2 41 0x30 4
- X
- X#O single8 mltnum %% 63 18
- X#O zonelo8 cpitch %% 127 26
- X#O zonehi8 cpitch %% 127 34
- X#O velosw8 velosw %% 2 50 0x30 4
- X#O poly8 poly %% 9 42 0x0F
- X#O modem8 mode %% 2 42 0x40 6 *1
- X#O moden8 num -- 1 50 0x40 6 *2
- X#O rcvch8 pnum %% 15 50 0x0F
- X#O trnsps8 keyshift %% 48 58
- X#O tune8 finetune %% 100 66
- X#O level8 num %% 100 74
- X#O output8 pan %% 2 42 0x30 4
- X
- X"autopitch", NULL, -1,-1, %%, visnum, 0, 127, 60, 0,
- X"autovol", NULL, -1,-1, %%, visnum, 0, 127, 63, 0,
- X"autodur", NULL, -1,-1, %%, visnum, 1, 20, 5, 0,
- X"autochan", NULL, -1,-1, %%, visnum, 1, 16, 1, 0,
- X
- XNULL, NULL, -1,-1, -1, -1, visnum, 0, 0, 0, 0
- X};
- X
- X/*
- X * k1mnum
- X *
- X * Convert a voice number (0 to 127) to the string displayed in the
- X * librarian (ie. A1 to D8 for multi, to d8 for singles).
- X */
- X
- Xchar *
- Xk1mnum(n)
- X{
- X static char v[4];
- X
- X if ( n < 0 || n > 63 )
- X return("???");
- X
- X v[0] = 'A' + (n >> 3);
- X if (v[0] > 'D') v[0] += ' ' - 4;
- X
- X (void)sprintf(v+1, "%d", (n % 8) + 1);
- X
- X return(v);
- X}
- X
- Xchar *
- Xvismltnum(n)
- X{ static char numnam[15];
- X
- X strcpy(numnam, k1mnum(n));
- X if (sngnames[n][0] > ' ') {
- X strcat(numnam, " ");
- X strcat(numnam, sngnames[n]);
- X }
- X return(numnam);
- X}
- X
- X/*
- X * k1nummlt
- X *
- X * Convert a display-style voice number (A1 to d8) to internal
- X * format (0 to 127).
- X */
- X
- Xk1nummlt(s)
- Xchar *s;
- X{
- X
- X int ld, rd;
- X
- X rd = s[0] - 'A';
- X if (rd > 3) rd -= ' ' - 4;
- X if (rd < 0 || rd > 7) return(-1);
- X
- X (void)sscanf(s+1, "%d", &ld);
- X if (ld < 1 || ld > 8) return(-1);
- X
- X return((rd << 3) + ld - 1);
- X
- X}
- X
- X/*
- X * k1mdin
- X *
- X * Take library bank 'data' and stuff values in the P array, by using
- X * the setval function.
- X */
- X
- Xk1mdin(data)
- Xchar *data;
- X{
- X /* The first RESERVESIZE bytes are reserved (arbitrarily) for the voice name */
- X#SETVAL
- X}
- X
- X/*
- X * k1mdout
- X *
- X * Take (possibly changed) parameters values out of the P array and
- X * put them back into the library bank 'data'.
- X */
- X
- Xk1mdout(data)
- Xchar *data;
- X{
- X#GETVAL
- X}
- X
- Xk1send1(function, voice)
- X{
- X if (Nvoices == 32) voice += 64;
- X
- X sendmidi(0xf0);
- X sendmidi(0x40); /* Kawai id */
- X sendmidi(Channel - 1); /* channel = 1 to 16 */
- X sendmidi(function); /* function */
- X sendmidi(0x00); /* group */
- X sendmidi(0x03); /* machine id number of K1 */
- X sendmidi(0x00); /* subcommand 1 = internal */
- X sendmidi(voice); /* subcommand 2 = voice 1 */
- X}
- X
- X/*
- X * k1msedit
- X *
- X * Send a single voice to the edit buffer of the K1. This will be whatever
- X * voice is currently selected.
- X * (So far as I know, one can't do this; this is here pro forma. -- gl)
- X */
- X
- Xk1msedit(data)
- Xchar *data;
- X{
- X/*
- X int cksum;
- X int n, dumpsize;
- X
- X k1send1(0x20, 0);
- X cksum = 0xa5;
- X
- X if (Nvoices == 32) dumpsize = K1MULTISIZE;
- X else dumpsize = K1SINGLESIZE;
- X
- X for(n = 0; n < dumpsize; n++) {
- X sendmidi(data[n] & 0x7f);
- X cksum += data[n] & 0x7f;
- X }
- X sendmidi(cksum & 0x7f);
- X sendmidi(EOX);
- X*/
- X}
- X
- X/*
- X * k1mnof
- X *
- X * Return a pointer to the voice name buried in library bank data.
- X */
- Xchar *
- Xk1mnof(data)
- Xchar *data;
- X{
- X static char currbuff[11];
- X char *p;
- X int m;
- X
- X p = currbuff;
- X for ( m = 0 ; m < 10 ; m++ )
- X *p++ = data[m];
- X *p = '\0';
- X return(currbuff);
- X}
- X
- X/*
- X * k1msnof
- X *
- X * Set the voice name buried in data to name.
- X */
- Xk1msnof(data,name)
- Xchar *data;
- Xchar *name;
- X{
- X char *p;
- X int m;
- X
- X for ( p = name, m = 0 ; *p != '\0' && m < 10 ; p++, m++ )
- X data[m] = *p;
- X for ( ; m < 10 ; m++ )
- X data[m] = ' ';
- X}
- X
- X/* k1msone - send a single voice to the K1 */
- Xk1msone(iv, data)
- Xint iv;
- Xchar *data;
- X{
- X int cksum;
- X int n, dumpsize;
- X
- X k1send1(0x20, iv);
- X cksum = 0xa5;
- X
- X if (Nvoices == 32) dumpsize = K1MULTISIZE;
- X else dumpsize = K1SINGLESIZE;
- X
- X for(n = 0; n < dumpsize; n++) {
- X sendmidi(data[n] & 0x7f);
- X cksum += data[n] & 0x7f;
- X }
- X sendmidi(cksum & 0x7f); /* checksum */
- X sendmidi(EOX);
- X
- X return(0);
- X}
- X
- X/* k1mgbulk - Request and read a bulk dump from the K1 */
- Xk1mgbulk(data)
- Xchar *data;
- X{
- X static char Buff[BUFSIZ];
- X int n, v, b2, ret = 1;
- X long begin, toolong;
- X int dumpsize;
- X
- X (void)sprintf(Buff,"\nA: ");
- X windstr(Buff);
- X
- X if (Nvoices == 32) dumpsize = K1MULTISIZE;
- X else dumpsize = K1SINGLESIZE;
- X
- X for(v = 0; v < Nvoices; v++) {
- X
- X flushmidi();
- X
- X if(v == 64) {
- X (void)sprintf(Buff,"\nB: ");
- X windstr(Buff);
- X }
- X if((((v > 63) ? (v - 64) : v) % 10) != 0) {
- X (void)sprintf(Buff, ".");
- X } else {
- X (void)sprintf(Buff,"%d", (((v > 63) ? (v - 64) : v) / 10));
- X }
- X windstr(Buff);
- X
- X /* request the dump */
- X if (!synthinfileflag) {
- X k1send1(0, v);
- X sendmidi(EOX);
- X }
- X
- X /* set up timeout */
- X begin = milliclock();
- X toolong = begin + (1000 * TIMEOUT);
- X
- X /* read header */
- X for(n = 0; n < 8; ) {
- X if ( STATMIDI ) {
- X b2 = (getmidi() & 0xff);
- X /* burn active sensing and timing clock */
- X if((b2 != 0xfe) && (b2 != 0xf8))
- X n++;
- X } else {
- X if ( milliclock() > toolong ) {
- X Reason = "Timeout waiting for header";
- X goto getout;
- X }
- X }
- X }
- X
- X /* read data */
- X for(n = 0; n < dumpsize; ) {
- X if ( STATMIDI ) {
- X b2 = (getmidi() & 0xff);
- X /* burn active sensing and timing clock */
- X if((b2 != 0xfe) && (b2 != 0xf8)) {
- X VOICEBYTE(data,v,n) = b2;
- X n++;
- X }
- X } else {
- X if ( milliclock() > toolong ) {
- X Reason = "Timeout reading data";
- X goto timeout;
- X }
- X }
- X }
- X
- X timeout:
- X if ( n != dumpsize ) {
- X Reason = "Timeout reading data!";
- X goto getout;
- X }
- X
- X /* read checksum */
- X for(n = 0; n < 1; ) {
- X if ( STATMIDI ) {
- X b2 = (getmidi() & 0xff);
- X /* burn active sensing and timing clock */
- X if((b2 != 0xfe) && (b2 != 0xf8))
- X n++;
- X } else {
- X if ( milliclock() > toolong ) {
- X Reason = "Timeout reading checksum";
- X goto getout;
- X }
- X }
- X }
- X
- X /* read EOX */
- X for(n = 0; n < 1; ) {
- X if ( STATMIDI ) {
- X b2 = (getmidi() & 0xff);
- X /* burn active sensing and timing clock */
- X if((b2 != 0xfe) && (b2 != 0xf8))
- X if ( b2 != EOX ) {
- X (void)sprintf(Buff,"EOX not received (%X)\n", b2);
- X Reason = Buff;
- X goto getout;
- X }
- X n++;
- X } else {
- X if ( milliclock() > toolong ) {
- X Reason = "Timeout reading EOX";
- X goto getout;
- X }
- X }
- X }
- X
- X } /* go back for another voice */
- X
- X Reason = "";
- X ret = 0; /* all's well */
- X
- Xgetout:
- X return(ret);
- X}
- X
- X/* k1msbulk - send a bulk dump to the K1 */
- Xk1msbulk(data)
- Xchar *data;
- X{
- X static char Buff[BUFSIZ];
- X int v, n, databyte, curoff, dumpsize;
- X int cksum;
- X
- X (void)sprintf(Buff,"\nA: ");
- X windstr(Buff);
- X
- X if (Nvoices == 32) dumpsize = K1MULTISIZE;
- X else dumpsize = K1SINGLESIZE;
- X
- X curoff = 0;
- X for(v = 0; v < Nvoices ; v++) {
- X if(v == 64) {
- X (void)sprintf(Buff,"\nB: ");
- X windstr(Buff);
- X }
- X if((((v > 63) ? (v - 64) : v) % 10) != 0) {
- X (void)sprintf(Buff, ".");
- X } else {
- X (void)sprintf(Buff,"%d", (((v > 63) ? (v - 64) : v) / 10));
- X }
- X
- X windstr(Buff);
- X k1send1(0x20, v);
- X cksum = 0xa5;
- X
- X for(n = 0; n < dumpsize; n++) {
- X databyte = data[n + curoff] & 0x7f;
- X sendmidi(databyte);
- X cksum += databyte;
- X }
- X sendmidi(cksum & 0x7f); /* checksum */
- X sendmidi(EOX);
- X curoff += Voicesize;
- X }
- X return(0);
- X}
- X
- X/* end */
- END_OF_FILE
- if test 10993 -ne `wc -c <'k1multi.mnu'`; then
- echo shar: \"'k1multi.mnu'\" unpacked with wrong size!
- fi
- # end of 'k1multi.mnu'
- fi
- if test -f 'pc-ints.asm' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'pc-ints.asm'\"
- else
- echo shar: Extracting \"'pc-ints.asm'\" \(12452 characters\)
- sed "s/^X//" >'pc-ints.asm' <<'END_OF_FILE'
- X@ab equ 6 ;use big model
- X; $Id: pc-ints.asm,v 1.6 89/05/06 17:13:38 lee Exp $
- X;
- X; the following constants are hardware specific to the MPU401 & OP4000
- X; MIDI interface controllers
- X; $Log: pc-ints.asm,v $
- X; Revision 1.6 89/05/06 17:13:38 lee
- X; rel. to comp.sources.misc
- X;
- X;
- X;
- XBASE_ADDRESS_MPU equ 330h
- XSTATUS_PORT_MPU equ BASE_ADDRESS_MPU + 1
- XCOMMAND_PORT_MPU equ BASE_ADDRESS_MPU + 1
- XDATA_PORT_MPU equ BASE_ADDRESS_MPU + 0
- XTx_EMT equ 40h ;midi transmitter ready for more data
- XRx_NEMT equ 80h ;midi receiver has data ready
- XMPU_INT equ 2
- XMPU_INT_MASK equ 4
- X;
- X; the remaining constants are for the AT&T PC6300 and compatible PC's
- X;
- XTIMER_INT equ 0
- XTIMER_INT_MASK equ 1
- XHW_INT_MASK equ MPU_INT_MASK OR TIMER_INT_MASK
- XINT_CTLR_PORT equ 20h ;port to send EOI command to
- XINT_CTLR_IMR equ 21h ;port to mask interrupts
- XEOI_CODE equ 20h ;EOI command
- XT_55MS equ 0000h ; 8253 value for 55 ms
- XT_5MS equ 174dh ; 8253 value for 5 ms
- XTIC_55MS equ 11 ; Number of timer tics to equal 55 ms
- XPIT_MODE equ 36h ; 8253 mode: 00 11 011 0 -> cntr0,LSB/MSB,mode 3,binary
- XPIT_CNT0 equ 40h ; Counter 0 port for 8253 PIT
- XPIT_CTRL equ 43h ; Control port for 8253 PIT
- XUSER_TMR equ 1ch ; User Timer (55 ms) Int. Vector
- X;
- X
- X;********************
- X;** macros **
- X;********************
- X;
- Xc_in macro ;this macro sets up a stack frame
- X push bp ;must save bp reg for 'c' progs
- X mov bp, sp ;set up frame pointer
- X push di
- X push si ;save register vars
- X endm
- X;
- Xc_out macro ;This macro cleans up for return to 'C'
- X pop si
- X pop di
- X mov sp, bp
- X pop bp ;restore caller's frame pointer
- X cld ;clear direction flag
- X ret ;and return
- X endm
- X;
- Xpush_all_regs macro
- X push es
- X push ds
- X push dx
- X push cx
- X push bx
- X push si
- X push di
- X push ax
- X push bp
- X endm
- X;
- Xpop_all_regs macro
- X pop bp
- X pop ax
- X pop di
- X pop si
- X pop bx
- X pop cx
- X pop dx
- X pop ds
- X pop es
- X endm
- X;
- Xenable_IMR macro num ;this macro clears (enables)
- X ;interrupts in the interrupt mask reg
- X in al, INT_CTLR_IMR ;read in current int mask
- X and al, 0ffh - num ;clear the requested IMR bit
- X out INT_CTLR_IMR, al ;and write it back out
- X endm
- X;
- Xdisable_IMR macro num ;disable interrupts in the IMR
- X in al, INT_CTLR_IMR ;read in current int mask
- X or al, num ;set the requested IMR bit
- X out INT_CTLR_IMR, al ;and write it out
- X endm
- X;
- Xack_int macro ;this macro sends non-specific EOI
- X ;to the int controller chip in the PC
- X mov al, EOI_CODE
- X out INT_CTLR_PORT, al
- X sti
- X endm
- X;
- X
- X;************************************************************
- X;** **
- X;** DATA GROUP DECLARATION **
- X;** **
- X;************************************************************
- X;
- X
- Xdgroup group data
- Xdata segment word public 'data'
- X assume ds:dgroup
- X;
- X; --- The following vars are used to manage a very small stack
- X; that is used for interrupt enable/disable stacking
- X;
- XINT_STACK_SIZE equ 8 * 1
- Xint_stack db (INT_STACK_SIZE/8) dup ('intstack')
- Xint_stack_pointer dw 0
- X;
- X; --- The following provide a circular character buffer used to
- X; store data received from the MIDI interface
- X;
- XBUFFER_SIZE equ 512
- X_wrt_index dw 0
- X_rd_index dw 0
- X_midi_buffer db BUFFER_SIZE dup (0)
- Xpublic _wrt_index
- Xpublic _rd_index
- Xpublic _midi_buffer
- X;
- X; --- The following vars are used to keep a running tally of the
- X; programmable timer ticks.
- X;
- X_hzcount dd 0
- Xint_cnt dw 0
- Xpublic _hzcount
- X;
- Xdata ends
- X;
- X
- X;************************************************************
- X;** **
- X;** CODE SEGMENT **
- X;** **
- X;** **
- X;************************************************************
- X;
- X;
- X extrn _fatal_dos_handler:far ;'C' routine to handle DOS errors
- X extrn _bye:far ; exit routine for Ctl-brk
- X
- X_code segment byte public 'code'
- X assume cs:_code
- X public _ctl_brk
- X public _asm_fatal_dos_handler
- X public _disable_ints
- X public _enable_ints
- X public _init_enable_MPU
- X public _init_enable_TIMER
- X public _reset_TIMER
- X public _write_data_MPU
- X public _read_MPU
- X public _midi_isr
- X public _tick_isr
- X
- X;
- X;************************************************************
- X;** **
- X;** INTERRUPT HANDLERS **
- X;** **
- X;** **
- X;************************************************************
- X_ctl_brk proc far
- X;
- X; Control-Break Interrupt Service Routine
- X;
- Xctl_st: cli ; make sure no interrupts
- X mov ax,ds
- X mov ss,ax ; ss = ds :: so chkstk() doesn't fail in quit()
- X mov sp,0fffeh ; and sp = hi mem
- X mov ax,1 ; exit code
- X sti ; turn interrupts back on
- X push ax
- X call _bye
- X pop bp ; not needed, never returns here
- X iret ; or here
- X_ctl_brk endp
- X;
- X; Fatal Dos Error Interrupt Service Routine
- X;
- X_asm_fatal_dos_handler proc far
- X push_all_regs ;save machine state
- X push di
- X push ax ;push args for function
- X mov ax, dgroup
- X mov ds, ax ;address data segment
- X mov es, ax ;and extra segmant
- X call _fatal_dos_handler ;handler(ax, di)
- X pop ax
- X pop ax
- X pop_all_regs
- X mov al,0 ;tell DOS to ignore error
- X iret
- X_asm_fatal_dos_handler endp
- X;
- X;
- X;************************************************************
- X;** MIDI_ISR **
- X;** This is the MPU int service routine **
- X;** It reads data from MPU data port until there is no more**
- X;** and stores in a circular buffer **
- X;************************************************************
- X;
- X_midi_isr proc far
- X push_all_regs ;save machine state
- X mov ax, dgroup
- X mov ds, ax
- X disable_IMR MPU_INT_MASK
- X sti
- Xdo_another:
- X mov dx, DATA_PORT_MPU
- X in al, dx ;read in the interrupt data from MPU
- X
- X inc _wrt_index ;bump up write pointer
- X cmp _wrt_index, 01ffh ;is index at top of buff?
- X jle wrt_index_ok
- X mov _wrt_index, 0 ;if yes, wraparound to bottom
- Xwrt_index_ok: ;of buffer
- X mov bx, _wrt_index
- X mov _midi_buffer[bx], al ;move data into buffer
- X
- X mov dx, STATUS_PORT_MPU ;DX = &status port
- X in al, dx ;read status port
- X and al, Rx_NEMT ;is there data to read?
- X jz do_another ;go back if so
- X;isr return
- X cli ;turn off system ints
- X enable_IMR MPU_INT_MASK
- X ack_int ;and acknowlege interrupt
- X pop_all_regs ;restore machine state
- X iret ;and leave
- X_midi_isr endp
- X;
- X;********************************************************************
- X;* TICK_ISR
- X;* The interrupt service routine for the programmable timer.
- X;* Timer is currently set at 5 ms. intervals.
- X;********************************************************************
- X;
- X_tick_isr proc far
- X;
- Xtmr_st: push ds
- X push ax
- X mov ax, dgroup
- X mov ds, ax ;must have our data segment
- X disable_IMR TIMER_INT_MASK
- X sti
- X add word ptr _hzcount, 1
- X adc word ptr _hzcount + 2, 0
- X inc int_cnt
- X cmp int_cnt,TIC_55MS
- X jge tm1
- X cli
- X enable_IMR TIMER_INT_MASK
- X ack_int
- X pop ax
- X pop ds
- X iret
- X
- Xtm1: mov int_cnt,0
- X int USER_TMR
- X cli
- X enable_IMR TIMER_INT_MASK
- X ack_int
- X pop ax
- X pop ds
- X iret
- X_tick_isr endp
- X
- X
- X;
- X;************************************************************
- X;** DISABLE_INTS() **
- X;** Called to disable interrupts. stacks old int **
- X;** status before disabling, so that nesting is **
- X;** preserved. **
- X;************************************************************
- X;
- X_disable_ints proc far
- X cli
- X in al, INT_CTLR_IMR ;read in current int mask
- X mov dl, al ;move it to dl
- X and dl, HW_INT_MASK ;extract the bit for MPU ints
- X mov bx, int_stack_pointer ;get current stack pointer
- X mov int_stack[bx], dl ;store out int status there
- X inc bx
- X mov int_stack_pointer, bx ;write back new stack pointer value
- X or al, HW_INT_MASK ;mask off int
- X out INT_CTLR_IMR, al ;and write it out
- X sti
- X ret
- X_disable_ints endp
- X;
- X;************************************************************
- X;** ENABLE_INTS() **
- X;** Restores whatever the int status was before **
- X;** DISABLE_INTS() was called. **
- X;** Note that calls to enable and disable must be matched **
- X;** or chaos will occur **
- X;************************************************************
- X;
- X_enable_ints proc far
- X cli
- X in al, INT_CTLR_IMR ;read in current int mask
- X and al, 0ffh - HW_INT_MASK ; get all the bits except the ones
- X ; for out ints
- X mov bx, int_stack_pointer ;get int stack pointer
- X dec bx ;move it down
- X mov int_stack_pointer, bx ;store it
- X or al, int_stack[bx] ;or in int status with old one
- X out INT_CTLR_IMR, al ;and write it out
- X sti ;turn ints on now
- X ret
- X_enable_ints endp
- X;
- X;************************************************************
- X;** INIT_ENABLE_MPU() **
- X;** Starts up the MPU ints. **
- X;** **
- X;************************************************************
- X;
- X_init_enable_MPU proc far
- X cli
- X enable_IMR MPU_INT_MASK
- X sti
- X ret
- X_init_enable_MPU endp
- X;;
- X;************************************************************
- X;** INIT_ENABLE_TIMER() **
- X;** Starts up the TIMER ints. **
- X;** **
- X;************************************************************
- X;
- X_init_enable_TIMER proc far
- X cli
- X; Set 8253 PIT for different timing
- X;
- X mov al,PIT_MODE
- X out PIT_CTRL,al ; Set 8253 mode
- X mov ax,T_5MS
- X out PIT_CNT0,al
- X mov al,ah
- X out PIT_CNT0,al ; Set new timing
- X enable_IMR TIMER_INT_MASK
- X sti
- X ret
- X_init_enable_TIMER endp
- X;
- X;
- X;************************************************************
- X;** RESET_TIMER() **
- X;** Sets timer values back to what they were **
- X;** **
- X;************************************************************
- X_reset_TIMER proc far
- X
- X disable_IMR TIMER_INT_MASK
- X mov al,PIT_MODE
- X out PIT_CTRL,al ; Set 8253 mode
- X mov ax,T_55MS
- X out PIT_CNT0,al
- X mov al,ah
- X out PIT_CNT0,al ; Reset timing
- X enable_IMR TIMER_INT_MASK
- X ret
- X_reset_TIMER endp
- X;
- X
- X;************************************************************
- X;** WRITE_DATA_MPU(DATA) **
- X;** sends a byte to the MPU data port **
- X;** waits for handshake **
- X;** **
- X;************************************************************
- X;
- X;
- X_write_data_MPU proc far
- X c_in
- X mov bx, @ab[bp] ;get data byte in bl reg
- X call write_sub ;and call fast sub
- X c_out ;leave
- X_write_data_MPU endp
- X;
- X;************************************************************
- X;** **
- X;** write_sub **
- X;** Writes data to MPU. on entry, byte in bl **
- X;** ax, cx, cx destroyed **
- X;************************************************************
- X;
- Xwrite_sub proc near
- X mov dx, STATUS_PORT_MPU ;set up pointer to MPU port
- Xwrite_clear_loop:
- X in al, dx
- X and al, Tx_EMT
- X jnz write_clear_loop
- X dec dx ;point to data reg
- X mov al, bl
- X out dx, al ;send out the data
- X ret
- Xwrite_sub endp
- X;
- X;************************************************************
- X;** read_MPU() **
- X;** reads a byte from the MPU eata port **
- X;** waits for handshake **
- X;** **
- X;************************************************************
- X;
- X_read_MPU proc far
- X c_in
- Xread_clear_loop:
- X mov dx, STATUS_PORT_MPU ;DX = &status port
- X in al, dx
- X and al, Rx_NEMT
- X jnz read_clear_loop
- X dec dx ;point to data reg
- X in al, dx
- X xor ah, ah
- X c_out
- X_read_MPU endp
- X
- X;
- X
- X_code ends
- X end
- X
- END_OF_FILE
- if test 12452 -ne `wc -c <'pc-ints.asm'`; then
- echo shar: \"'pc-ints.asm'\" unpacked with wrong size!
- fi
- # end of 'pc-ints.asm'
- fi
- if test -f 'pc-mach.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'pc-mach.c'\"
- else
- echo shar: Extracting \"'pc-mach.c'\" \(11518 characters\)
- sed "s/^X//" >'pc-mach.c' <<'END_OF_FILE'
- X/* $Id: pc-mach.c,v 1.6 89/05/06 17:13:39 lee Exp $
- X *
- X * Glib - Generic LIBrarian and editor
- X *
- X * Machine dependent stuff for MIDI programs.
- X * Time Thompson
- X *
- X * This is for MS-DOS machines. The screen operations should
- X * work okay, but the MIDI I/O needs to be worked on. It may
- X * or may not be fast enough on some machines.
- X * $Log: pc-mach.c,v $
- X * Revision 1.6 89/05/06 17:13:39 lee
- X * rel. to comp.sources.misc
- X *
- X */
- X
- X#include "glib.h"
- X
- Xint Rows = 24;
- Xint Cols = 80;
- X
- Xchar *
- Xalloc(n)
- X{
- X char *p;
- X
- X if ( (p=malloc((unsigned)n)) == (char *)NULL ) {
- X printf("*** Whoops *** alloc has failed?!? No more memory!\n");
- X fflush(stdout);
- X bye();
- X }
- X return(p);
- X}
- X
- Xflushmidi()
- X{
- X while ( STATMIDI )
- X getmidi();
- X}
- X
- X/* getmouse - get currect row and column of mouse */
- Xgetmouse(amr,amc)
- Xint *amr;
- Xint *amc;
- X{
- X *amr = -1;
- X *amc = -1;
- X}
- X
- X/* statmouse - return mouse button state (0=nothing pressed,1=left,2=right) */
- Xstatmouse()
- X{
- X return(-1);
- X}
- X
- X/* Return when either a console key or mouse button is pressed. */
- Xmouseorkey()
- X{
- X return(getconsole());
- X}
- X
- X#ifdef C86
- Xgetch()
- X{
- X struct regval sreg, rreg;
- X sreg.ax = 0x0000;
- X sysint(0x16, &sreg, &rreg);
- X return(rreg.ax & 0x7f);
- X}
- X#endif
- X
- Xwindinit()
- X{
- X}
- X
- Xwindgoto(r,c)
- Xint r,c;
- X{
- X#ifdef C86
- X struct regval sreg, rreg;
- X sreg.ax = 0x200;
- X sreg.bx = 0;
- X sreg.dx = (r<<8) | c ;
- X sysint(0x10, &sreg, &rreg);
- X#endif
- X#ifdef TURBOC
- X gotoxy(1+c,1+r);
- X#endif
- X}
- X
- Xwinderaserow(r)
- X{
- X#ifdef C86
- X struct regval sreg, rreg;
- X sreg.ax = 0x0600;
- X sreg.bx = 0;
- X sreg.cx = (r<<8); /* urow, lcol */
- X sreg.dx = (r<<8) | 79;
- X sysint(0x10, &sreg, &rreg);
- X#endif
- X#ifdef TURBOC
- X gotoxy(1,r+1);
- X clreol();
- X#endif
- X}
- X
- Xwindexit()
- X{
- X /* windgoto(23,0);
- X windrefresh();
- X nocbreak();
- X nl();
- X echo();
- X endwin(); */
- X}
- X
- Xwindclear()
- X{
- X#ifdef C86
- X struct regval sreg, rreg;
- X sreg.ax = 0x0600;
- X sreg.bx = 0;
- X sreg.cx = 0; /* urow, lcol */
- X sreg.dx = (24<<8) | 79;
- X sysint(0x10, &sreg, &rreg);
- X#endif
- X#ifdef TURBOC
- X clrscr();
- X#endif
- X}
- X
- X/* windgets - get a line of input from the console, handling backspaces */
- Xwindgets(s)
- Xchar *s;
- X{
- X char *origs = s;
- X int c;
- X
- X while ( (c=getconsole()) != '\n' && c!='\r' && c!= EOF ) {
- X if ( c == '\b' ) {
- X if ( s > origs ) {
- X windstr("\b \b");
- X s--;
- X }
- X }
- X else {
- X windputc(c);
- X *s++ = c;
- X }
- X windrefresh();
- X }
- X *s = '\0';
- X}
- X
- Xwindstr(s)
- Xchar *s;
- X{
- X int c;
- X
- X while ( (c=(*s++)) != '\0' )
- X windputc(c);
- X}
- X
- Xwindputc(c)
- Xint c;
- X{
- X putchar(c);
- X}
- X
- Xwindrefresh()
- X{
- X}
- X
- Xbeep()
- X{
- X putchar('\007');
- X}
- X
- Xwindhigh()
- X{
- X}
- X
- Xwindnorm()
- X{
- X}
- X
- X/****************
- X * openls(), nextls(), and closels() are used to scan the current directory.
- X ***************/
- X
- Xint first = 1;
- Xopenls()
- X{
- X first = 1;
- X}
- Xchar *
- Xnextls()
- X{
- X static struct ffblk ffblk;
- X int n;
- X
- X if ( first ) {
- X n = findfirst("*.*",&ffblk,0);
- X first = 0;
- X }
- X else
- X n = findnext(&ffblk);
- X
- X if ( n == 0 )
- X return(ffblk.ff_name);
- X else
- X return((char *)NULL);
- X}
- Xclosels()
- X{
- X}
- X
- X#ifdef OLDSTUFF
- X/*
- X * The following MPU code has been provided by Steve Frysinger (moss!spf).
- X */
- X
- X#define STATUS_PORT 0x0331
- X#define COMMAND_PORT 0x0331
- X#define DATA_PORT 0x0330
- X#define DATA_READY_MASK 0x40
- X#define DATA_AVAIL_MASK 0x80
- X
- Xint send_command_4001(val) /* Patterned after Voyetra's reset_4001() */
- Xunsigned val;
- X{
- X unsigned x = 0;
- X int flag;
- X int ack_count,time_count;
- X int retval=1; /* Assume success */
- X inportb(DATA_PORT);
- X for (time_count=5000,flag=1;time_count&&flag;time_count--)
- X {
- X if (!(inportb(STATUS_PORT)&DATA_READY_MASK)) flag=0;
- X }
- X if (flag)
- X {
- X fprintf(stderr,"Command timeout waiting for port!\n");
- X retval = -1;
- X }
- X else
- X {
- X outportb(COMMAND_PORT,val);
- X for (time_count=10000,ack_count=5,flag=0;!flag;)
- X {
- X if ((inportb(STATUS_PORT)&DATA_AVAIL_MASK))
- X {
- X time_count--;
- X if (!time_count)
- X {
- X flag++;
- X fprintf(stderr,"Command timeout waiting for ACK.\n");
- X retval = -1;
- X }
- X }
- X else
- X {
- X x = (unsigned)inportb(DATA_PORT);
- X if (x == 0xfe)
- X {
- X flag++;
- X fprintf(stderr,"Got command acknowledgement\n");
- X }
- X else
- X {
- X ack_count--;
- X if (!ack_count)
- X {
- X printf("Too many data bytes without ACK\n");
- X retval = -1;
- X }
- X }
- X }
- X }
- X }
- X return(retval);
- X} /* send_command_4001 */
- X#endif
- X
- X/*
- X * Acknowledgements to John Helton for additions to support ATT PC6300 w/
- X * MPU401 and OP4000 MIDI Interface Controllers.
- X * PC6300 support uses Borland TurboC 'C' compiler, large model
- X *
- X */
- X#define QUIT 1
- X#define NOQUIT 0
- X
- Xvoid interrupt (*oldint0)();
- Xvoid interrupt (*oldint2)();
- Xvoid interrupt (*oldint1b)();
- Xvoid interrupt (*oldint23)();
- Xvoid interrupt (*oldint24)();
- Xvoid interrupt ctr_brk_handler();
- Xvoid interrupt fatal_err_hndlr();
- X
- Xvoid interrupt far tick_isr();
- Xvoid interrupt far midi_isr();
- Xextern unsigned long hzcount;
- Xextern char midi_buffer[];
- Xextern int wrt_index, rd_index;
- X
- Xextern unsigned _stklen; /* Turbo C specific */
- X
- Xint Nextpcchar = EOF;
- Xint Fakemidi = 0;
- Xint (*Intfunc)() = NULL;
- X
- Xhello()
- X{
- X _stklen = 50000;
- X hzcount = 0L; /* init timer & buffer globals */
- X wrt_index = rd_index = 0;
- X if (!setup_MIC()) /* Set up the Midi Interface Ctrl */
- X {
- X if ( fisatty(stdout) )
- X printf("Can't initialize midi interface\n");
- X Fakemidi = 1;
- X reset_ints(NOQUIT); /* restore interrupts to a suitable
- X condition to keep running without
- X the Midi Interface (for testing) */
- X return;
- X }
- X send_msg(UART, COMMAND_MSG); /* run the MIC in dumb mode */
- X return;
- X}
- X
- Xrtend()
- X{
- X reset_MIC();
- X}
- X
- Xbye()
- X{
- X system_exit();
- X}
- X
- Xflushconsole()
- X{ return; }
- X
- Xgetconsole()
- X{
- X int c;
- X
- X if ( Nextpcchar != EOF ) {
- X c = Nextpcchar;
- X Nextpcchar = EOF;
- X }
- X else {
- X c = getch();
- X }
- X return(c);
- X}
- X
- Xputconsole(c)
- X{
- X putch(c);
- X}
- X
- X/* getmidi reads data out of the circular midi buffer */
- Xgetmidi()
- X{
- X static char mbuff[1];
- X unsigned char *p;
- X
- X while ( wrt_index == rd_index)
- X ;
- X rd_index++;
- X if (rd_index > 511) rd_index = 0;
- X mbuff[0] = midi_buffer[rd_index];
- X return (mbuff[0] & 0xff);
- X}
- X
- Xsendmidi(val)
- Xint val;
- X{
- X unsigned char p[1];
- X p[0] = val;
- X putnmidi(1,p);
- X}
- X
- Xputnmidi(n,p)
- Xchar *p;
- X{
- X while ( n-- > 0 ) {
- X int c = (*p++) & 0xff;
- X if ( Fakemidi )
- X printf("putmidi(d=%d x=%x o=%o)\n",c,c,c);
- X else
- X write_data_MPU(c);
- X }
- X}
- X
- Xresetclock()
- X{
- X hzcount = 0L;
- X}
- X
- Xlong
- Xmilliclock()
- X{
- X return (hzcount*5L);
- X}
- X
- X/* filetime - Return the modification time of a file in seconds. */
- Xlong
- Xfiletime(fn)
- Xchar *fn; /* file name */
- X{
- X struct stat s;
- X
- X if ( stat(fn,&s) == -1 )
- X return(-1);
- X return(s.st_mtime);
- X}
- X
- X/* currtime - Return current time in seconds (consistent with filetime()) */
- Xlong
- Xcurrtime()
- X{
- X long time();
- X return ( time((long *)0) );
- X}
- X
- Xfisatty(f)
- XFILE* f;
- X{
- X return(isatty(fileno(f)));
- X}
- X
- X/*
- X * send_msg(COM, TYPE, PTR, LENGTH)
- X * will send command to Midi Interface Controller (MIC) Command port,
- X * then either return, wait for data or send data
- X */
- X
- Xsend_msg(com, type, ptr, length)
- Xint com, type, length;
- Xchar *ptr;
- X{
- X int acked;
- X int x;
- X
- X while ( NOT_READY_FOR_DATA_MIC());
- X disable_ints();
- X COMMAND_OUT_MIC((char) com); /* send the command to the MIC */
- X for(acked=0; !acked; ) { /* wait until our command is acked */
- X x = read_MPU(); /* get a byte back from the MIC */
- X if (x == ACK) acked++; /* done if ACK received */
- X else write_rcv_buff(x); /* deal with this input stream first */
- X }
- X if (type == WRITE_MSG) /* if write request... */
- X for (; length; ptr++, length--) write_data_MPU(*ptr);
- X /* write all the bytes to the MIC */
- X enable_ints(); /* ints restored to where they were
- X before we shut them off */
- X}
- X
- X
- X/* WRITE_RCV_BUFF(INPUT)
- X * part of the command handshake sequence. Input read from the
- X * midi data port is saved in wraparound FIFO
- X*/
- X
- Xwrite_rcv_buff(val)
- Xint val;
- X{
- X wrt_index++;
- X if (wrt_index > 511) wrt_index = 0;
- X midi_buffer[wrt_index] = (char) val;
- X}
- X
- X/*
- X * SETUP_MIC()
- X * resets MIC, sets up int vectors and enables int system
- X * Returns - true if MIC set ok
- X */
- X
- Xstatic setup_MIC()
- X{
- X int retval;
- X
- X set_ints(); /* set the new interrupt vectors */
- X init_enable_MPU(); /* turn on interrupt system for first time */
- X retval = reset_MIC(); /* try to reset MIC */
- X if (!retval) retval = reset_MIC(); /* if no good, try again */
- X init_enable_TIMER(); /* turn on timer interrupt if reset ok*/
- X return(retval);
- X}
- X
- X/*
- X * RESET_MIC()
- X * attempts to do a low level software reset on the MIC
- X * returns - true if success
- X */
- X
- Xreset_MIC()
- X{
- X unsigned x = 0;
- X int flag;
- X int ack_count, time_count;
- X int retval=1; /* assume success */
- X
- X disable_ints(); /* disable interrupts */
- X READ_DATA_MIC(); /* Clear out any data in receiver */
- X /* Here we will loop until ready for data, or we give up */
- X for (time_count=5000, flag=1; time_count && flag; time_count--) {
- X /* if MIC ready for data, we can quit loop */
- X if (!(NOT_READY_FOR_DATA_MIC())) flag=0;
- X }
- X /* if timed out before we got ready for data, return flag couldn't reset */
- X if (flag){
- X retval = 0;
- X }
- X else {
- X COMMAND_OUT_MIC(RESET); /* Send the reset command */
- X /* loop here till time out, or ack recvd */
- X for (time_count=10000, ack_count=5, flag=0; !flag;) {
- X if ((NOT_DATA_AVAILABLE_MIC())) { /* if no data from MIC */
- X time_count--; /* count one more wait */
- X if (!time_count) {
- XBAD_RESET:
- X flag++; /* if time out, note it */
- X retval=0; /* and note failure */
- X }
- X }
- X else { /* If there is data coming back form MIC */
- X x = (unsigned) READ_DATA_MIC(); /* ...read it */
- X if (x == ACK) { /* If data is the ACK message */
- X flag++; /* note we are done, and no failure */
- X }
- X else { /* if data back from MIC wasn't ack */
- X ack_count--;/* note that we got something that isn't ack */
- X if (!ack_count) goto BAD_RESET;
- X /* If we get too many data bytes back from
- X MIC with no ack, give up */
- X }
- X }
- X }
- X }
- X enable_ints(); /* turn ints back on */
- X return(retval);
- X}
- X
- X/*
- X * SYSTEM_EXIT()
- X * called to leave program. resets ints and exits
- X */
- Xsystem_exit()
- X{
- X reset_MIC();
- X disable_ints();
- X reset_ints(QUIT); /* put all the int vectors back where they were */
- X reset_TIMER();
- X enable_ints();
- X windexit(0);
- X exit();
- X}
- X
- X/*
- X * hi level interrupt routines
- X */
- X
- Xvoid interrupt
- Xctr_brk_handler()
- X{
- X if ( Intfunc != NULL )
- X (*Intfunc)();
- X printf("interrupts reset; BYE!\n");
- X system_exit();
- X}
- X
- Xvoid interrupt
- Xfatal_err_hndlr()
- X{
- X fatal_dos_handler();
- X}
- X
- Xfatal_dos_handler() /* called by fatal error handler ISR */
- X{
- X printf("got fatal error; BYE!\n");
- X system_exit();
- X}
- X
- Xset_ints()
- X{
- X oldint0 = getvect(0x08); /* timer interrupt on irq0 */
- X setvect(0x08, tick_isr);
- X oldint2 = getvect(0x0a); /* midi interrupt on irq2 */
- X setvect(0x0a, midi_isr);
- X oldint1b = getvect(0x1b); /* the rest of these are dos & bios ints */
- X setvect(0x1b, ctr_brk_handler);
- X oldint23 = getvect(0x23);
- X setvect(0x23, ctr_brk_handler);
- X oldint24 = getvect(0x24);
- X setvect(0x24, fatal_err_hndlr);
- X}
- X
- Xreset_ints(reset_type)
- X{
- X if (reset_type == QUIT) {
- X setvect(0x08, oldint0);
- X setvect(0x1b, oldint1b);
- X setvect(0x23, oldint23);
- X setvect(0x24, oldint24);
- X }
- X setvect(0x0a, oldint2); /* only need to reset one hardware interrupt
- X if we're not going to quit */
- X}
- X
- Xsignal(type,func)
- Xint (*func)();
- X{
- X if ( type == SIGINT ) {
- X if ( func == SIG_IGN )
- X Intfunc = NULL;
- X else
- X Intfunc = func;
- X }
- X}
- END_OF_FILE
- if test 11518 -ne `wc -c <'pc-mach.c'`; then
- echo shar: \"'pc-mach.c'\" unpacked with wrong size!
- fi
- # end of 'pc-mach.c'
- fi
- echo shar: End of archive 6 \(of 15\).
- cp /dev/null ark6isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 15 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-
-